#include "ast.h"
#include "param_list.h"

struct param_list * param_list_create ( 
  char * name,
  struct type * type, 
  struct param_list *next )
{
 struct param_list *a = malloc(sizeof(*a));

 a->name = name;
 a->type = type;
 a->next = next;

 return a;
}

void param_list_print(struct param_list * p)
{
  if (!p) return;
  type_print (p->type);
  printf(" %s", p->name);
  if (p->next) printf(", ");
  param_list_print(p->next);
}

void param_list_resolve(struct param_list * p, int L)
{
  if (!p) return;
  if (p->type->kind == TYPE_KIND_VOID || p->type->kind == TYPE_KIND_FUNCTION)
  {
    //error:
    printf("Error: function parameter \"%s\" declared as void (or somehow a func).\n \
This is not allowed.  Make sure all your function accept arguments only of types\n \
int, boolean, string, or char\n", p->name);
    type_print(p->type);
    printf("%d\n", p->type->kind);

    exit(1);
  }
  struct symbol * s = symbol_create(SYMBOL_KIND_PARAM, L, p->type, p->name, 1);
  scope_bind (p->name, s);
  param_list_resolve(p->next, L+1);
  
}

void param_list_typecheck(struct param_list *p, struct expr * a)
{
  if (!p && !a) return;
  if (!a || !p)
  {
    printf("Error: the number of parameters and args do not match.\n" );  
    exit(1);
  }
  if (type_compare(p->type, expr_typecheck(a->left) ) )
  {  param_list_typecheck(p->next, a->right); }
  else
  {
    printf("Error: type mismatch between param %s and its arg.\n", p->name );  
    exit(1);
  }

}

